/*
 *
 * Copyright(c) 2018-2019 chj <1019487871@qq.com>
 * QQ: 1019487871
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "los.h"

#define CN_INT_BITS_WORDS   ((CN_INT_LINE_LAST+CN_CPU_BITS)/CN_CPU_BITS)

struct los_int_reg_t volatile * const los_int_reg
                        =  (struct los_int_reg_t *)0xe000e100;

void
losbsp_contact_asyn(void)
{
    __asm volatile(
        "mov    r0, #0 \n\t"
        "msr    basepri, r0 \n\t"
    );
}

void
losbsp_cut_asyn(void)
{
    __asm volatile(
        "mov    r0,#0xff \n\t"
        "msr    basepri, r0 \n\t"
    );
}

void
losbsp_contact_trunk(void)
{
    __asm volatile(
        "cpsie  i \n\t"
    );
}

void
losbsp_cut_trunk(void)
{
    __asm volatile(
        "cpsid  i \n\t"
    );
}

bool_t
losbsp_contack_line(uint32_t ufl_line)
{
    if( ufl_line > CN_INT_LINE_LAST )
        return false;
    los_int_reg->setena[(ufl_line>>0x05)] =
                        (uint32_t)0x01<<(ufl_line & (uint32_t)0x1F);
    return true;
}

bool_t
losbsp_cut_line(uint32_t ufl_line)
{
    if( ufl_line > CN_INT_LINE_LAST )
        return false;
    los_int_reg->clrena[(ufl_line >> 0x05)] =
                    (uint32_t)0x01 << (ufl_line & (uint32_t)0x1F);
    return true;
}

bool_t
losbsp_clear_line(uint32_t ufl_line)
{
    uint32_t  offset=0,ucl_msk=0;
    if( ufl_line > CN_INT_LINE_LAST )
        return false;
    offset = ufl_line>>5;
    ucl_msk = 1<<(ufl_line & 0x1f);
    los_int_reg->clrpend[offset] = ucl_msk;
    return true;
}

void
losbsp_clear_all_line(void)
{
    uint32_t ufl;
    for(ufl=0; ufl < CN_INT_BITS_WORDS; ufl++)
        los_int_reg->clrpend[ufl] = 0xffffffff;
}

bool_t
losbsp_query_line(uint32_t ufl_line)
{
    uint32_t  offset=0,ucl_msk=0;
    if( ufl_line > CN_INT_LINE_LAST )
        return false;
    offset = ufl_line>>5;
    ucl_msk = 1<<(ufl_line & 0x1f);
    if(los_int_reg->setpend[offset] & ucl_msk)
    {
        los_int_reg->clrpend[offset] = ucl_msk;
        return true;
    }else
        return false;
}

bool_t
losbsp_setto_asyn_signal(uint32_t ufl_line)
{
    if( ufl_line > CN_INT_LINE_LAST )
        return false;
    los_int_reg->pri[ufl_line] = 0xff;
    return true;
}

bool_t
losbsp_setto_real(uint32_t ufl_line)
{
    if( (ufl_line > CN_INT_LINE_LAST))
        return false;
    los_int_reg->pri[ufl_line] = CN_REAL_PRIO_DEFAULT;
    return true;
}

bool_t
losbsp_set_prio(uint32_t ufl_line,uint32_t prio)
{
    if(ufl_line > CN_INT_LINE_LAST)
        return false;
    los_int_reg->pri[ufl_line] = prio & (uint32_t)0xff;
    return true;
}

void
losbsp_cm_cpsie_f(void)
{
    __asm volatile(
            "cpsie  f \n\t"
    );
}

void
losbsp_int_init(void)
{
    uint32_t ufl_line=0;
    losbsp_cut_trunk();
    losbsp_clear_all_line();
    los_scb_reg->CCR |= 1<<bo_scb_ccr_usersetmpend;
    for(ufl_line=0;ufl_line <= CN_INT_LINE_LAST;ufl_line++)
    {
        los_int_reg->pri[ufl_line] = 0xff;
    }

    for(ufl_line=0; ufl_line < CN_INT_BITS_WORDS; ufl_line++)
    {
        los_int_reg->clrena[ufl_line]=0xffffffff;
        los_int_reg->clrpend[ufl_line]=0xffffffff;
    }
    losbsp_contact_trunk();
    losbsp_cm_cpsie_f();
}

